package com.example.demo;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.*;
import java.text.SimpleDateFormat;

@WebServlet(name = "AlarmInfoServlet", value = "/AlarmInfoServlet")
public class AlarmInfoServlet extends HttpServlet {
    private static final String DB_URL = "jdbc:mysql://172.18.64.254:3306/三人行?useSSL=false&serverTimezone=UTC&characterEncoding=utf8";
    private static final String DB_USER = "webdb";
    private static final String DB_PASSWORD = "webdb";

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        response.setContentType("application/json;charset=utf-8");
        PrintWriter out = response.getWriter();

        String action = request.getParameter("action");
        if ("list".equals(action)) {
            listAlarms(out);  // 查询所有报警记录（支持与预案关联展示）
        } else if ("get".equals(action)) {
            getAlarm(request, out);  // 获取单个报警详情
        } else if ("delete".equals(action)) {
            deleteAlarm(request, out);  // 删除报警记录
        } else {
            out.println("{\"error\": \"无效的操作(action)\"}");
        }
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        response.setContentType("application/json;charset=utf8");
        PrintWriter out = response.getWriter();

        String action = request.getParameter("action");
        if ("add".equals(action)) {
            addAlarm(request, out);  // 添加报警记录
        } else if ("update".equals(action)) {
            updateAlarm(request, out);  // 更新报警记录
        } else if ("handle".equals(action)) {
            handleAlarm(request, out);  // 处理报警（标记为已处理）
        } else {
            out.println("{\"error\": \"无效的操作(action)\"}");
        }
    }

    // 加载所有报警记录（前端可关联预案名称展示）
    private void listAlarms(PrintWriter out) {
        try (Connection conn = getConnection();
             Statement stmt = conn.createStatement();
             ResultSet rs = stmt.executeQuery("SELECT * FROM alarm_info ORDER BY alarm_time DESC")) {

            StringBuilder json = new StringBuilder("[");
            while (rs.next()) {
                if (json.length() > 1) json.append(",");
                json.append("{")
                        .append("\"id\":").append(rs.getInt("id")).append(",")
                        .append("\"alarmDevice\":\"").append(escapeJson(rs.getString("alarm_device"))).append("\",")
                        .append("\"alarmType\":\"").append(escapeJson(rs.getString("alarm_type"))).append("\",")
                        .append("\"alarmParam\":\"").append(escapeJson(rs.getString("alarm_param"))).append("\",")
                        .append("\"alarmValue\":").append(rs.getDouble("alarm_value")).append(",")
                        .append("\"thresholdValue\":").append(rs.getDouble("threshold_value")).append(",")
                        .append("\"alarmArea\":\"").append(escapeJson(rs.getString("alarm_area"))).append("\",")
                        .append("\"alarmTime\":\"").append(formatDateTime(rs.getTimestamp("alarm_time"))).append("\",")
                        .append("\"status\":\"").append(rs.getString("status")).append("\",")
                        .append("\"handler\":\"").append(escapeJson(rs.getString("handler"))).append("\"")
                        .append("}");
            }
            json.append("]");
            out.println(json.toString());
        } catch (SQLException e) {
            e.printStackTrace();
            out.println("{\"error\": \"加载失败: " + e.getMessage() + "\"}");
        }
    }

    // 获取单个报警详情（用于编辑）
    private void getAlarm(HttpServletRequest request, PrintWriter out) {
        String idParam = request.getParameter("id");
        if (idParam == null || idParam.trim().isEmpty()) {
            out.println("{\"error\": \"缺少必要参数(id)\"}");
            return;
        }

        try {
            int id = Integer.parseInt(idParam);
            try (Connection conn = getConnection();
                 PreparedStatement pstmt = conn.prepareStatement("SELECT * FROM alarm_info WHERE id = ?")) {

                pstmt.setInt(1, id);
                ResultSet rs = pstmt.executeQuery();
                if (rs.next()) {
                    StringBuilder json = new StringBuilder("{");
                    json.append("\"id\":").append(rs.getInt("id")).append(",")
                            .append("\"alarmDevice\":\"").append(escapeJson(rs.getString("alarm_device"))).append("\",")
                            .append("\"alarmType\":\"").append(escapeJson(rs.getString("alarm_type"))).append("\",")
                            .append("\"alarmParam\":\"").append(escapeJson(rs.getString("alarm_param"))).append("\",")
                            .append("\"alarmValue\":").append(rs.getDouble("alarm_value")).append(",")
                            .append("\"thresholdValue\":").append(rs.getDouble("threshold_value")).append(",")
                            .append("\"alarmArea\":\"").append(escapeJson(rs.getString("alarm_area"))).append("\",")
                            .append("\"alarmTime\":\"").append(formatDateTime(rs.getTimestamp("alarm_time"))).append("\",")
                            .append("\"status\":\"").append(rs.getString("status")).append("\",")
                            .append("\"handler\":\"").append(escapeJson(rs.getString("handler"))).append("\"}");
                    out.println(json.toString());
                } else {
                    out.println("{\"error\": \"未找到记录（ID=" + id + "）\"}");
                }
            }
        } catch (NumberFormatException e) {
            out.println("{\"error\": \"参数格式错误 - id必须为数字（输入值：" + idParam + "）\"}");
        } catch (SQLException e) {
            e.printStackTrace();
            out.println("{\"error\": \"获取数据失败 - " + e.getMessage() + "\"}");
        }
    }

    // 添加报警记录
    private void addAlarm(HttpServletRequest request, PrintWriter out) {
        String alarmType = request.getParameter("alarmType");
        String alarmArea = request.getParameter("alarmArea");
        String alarmParam = request.getParameter("alarmParam");
        String alarmValueStr = request.getParameter("alarmValue");
        String alarmTimeStr = request.getParameter("alarmTime");

        if (alarmType == null || alarmArea == null || alarmParam == null ||
                alarmValueStr == null || alarmTimeStr == null) {
            out.println("{\"error\": \"缺少必要参数\"}");
            return;
        }

        try {
            double alarmValue = Double.parseDouble(alarmValueStr);
            String formattedTime = alarmTimeStr.replace("T", " ") + ":00";
            Timestamp alarmTime = Timestamp.valueOf(formattedTime);

            // 获取阈值（与应急预案联动时，可根据阈值判断火情等级匹配预案）
            double thresholdValue = getThresholdValue(alarmParam);

            try (Connection conn = getConnection();
                 PreparedStatement pstmt = conn.prepareStatement(
                         "INSERT INTO alarm_info (alarm_device, alarm_type, alarm_param, alarm_value, threshold_value, alarm_area, alarm_time, status) " +
                                 "VALUES (?, ?, ?, ?, ?, ?, ?, '待处理')")) {

                // 根据报警参数自动匹配设备类型
                String device = "温度".equals(alarmParam) ? "温感设备" :
                        ("湿度".equals(alarmParam) ? "湿度传感器" : "烟感设备");
                String type = alarmParam + "超标";  // 自动生成报警类型（如：温度超标）

                pstmt.setString(1, device);
                pstmt.setString(2, type);
                pstmt.setString(3, alarmParam);
                pstmt.setDouble(4, alarmValue);
                pstmt.setDouble(5, thresholdValue);
                pstmt.setString(6, alarmArea);
                pstmt.setTimestamp(7, alarmTime);
                pstmt.executeUpdate();
                out.println("{\"success\": true}");
            }
        } catch (NumberFormatException e) {
            out.println("{\"error\": \"参数格式错误 - alarmValue必须为数字（输入值：" + alarmValueStr + "）\"}");
        } catch (IllegalArgumentException e) {
            out.println("{\"error\": \"日期格式错误（需为 yyyy-MM-ddTHH:mm，输入值：" + alarmTimeStr + "）\"}");
        } catch (SQLException e) {
            e.printStackTrace();
            out.println("{\"error\": \"添加失败 - " + e.getMessage() + "\"}");
        }
    }

    // 更新报警记录
    private void updateAlarm(HttpServletRequest request, PrintWriter out) {
        String idParam = request.getParameter("id");
        String alarmType = request.getParameter("alarmType");
        String alarmArea = request.getParameter("alarmArea");
        String alarmParam = request.getParameter("alarmParam");
        String alarmValueStr = request.getParameter("alarmValue");
        String alarmTimeStr = request.getParameter("alarmTime");

        if (idParam == null || alarmType == null || alarmArea == null ||
                alarmParam == null || alarmValueStr == null || alarmTimeStr == null) {
            out.println("{\"error\": \"缺少必要参数\"}");
            return;
        }

        try {
            int id = Integer.parseInt(idParam);
            double alarmValue = Double.parseDouble(alarmValueStr);
            String formattedTime = alarmTimeStr.replace("T", " ") + ":00";
            Timestamp alarmTime = Timestamp.valueOf(formattedTime);

            // 获取阈值（更新时同步更新阈值）
            double thresholdValue = getThresholdValue(alarmParam);

            try (Connection conn = getConnection();
                 PreparedStatement pstmt = conn.prepareStatement(
                         "UPDATE alarm_info SET " +
                                 "alarm_device = ?, " +
                                 "alarm_type = ?, " +
                                 "alarm_param = ?, " +
                                 "alarm_value = ?, " +
                                 "threshold_value = ?, " +
                                 "alarm_area = ?, " +
                                 "alarm_time = ? " +
                                 "WHERE id = ?")) {

                String device = "温度".equals(alarmParam) ? "温感设备" :
                        ("湿度".equals(alarmParam) ? "湿度传感器" : "烟感设备");
                String type = alarmParam + "超标";

                pstmt.setString(1, device);
                pstmt.setString(2, type);
                pstmt.setString(3, alarmParam);
                pstmt.setDouble(4, alarmValue);
                pstmt.setDouble(5, thresholdValue);
                pstmt.setString(6, alarmArea);
                pstmt.setTimestamp(7, alarmTime);
                pstmt.setInt(8, id);

                int rows = pstmt.executeUpdate();
                if (rows > 0) {
                    out.println("{\"success\": true}");
                } else {
                    out.println("{\"error\": \"未找到记录（ID=" + id + "）\"}");
                }
            }
        } catch (NumberFormatException e) {
            out.println("{\"error\": \"参数格式错误 - id/alarmValue必须为数字\"}");
        } catch (IllegalArgumentException e) {
            out.println("{\"error\": \"日期格式错误（需为 yyyy-MM-ddTHH:mm）\"}");
        } catch (SQLException e) {
            e.printStackTrace();
            out.println("{\"error\": \"更新失败 - " + e.getMessage() + "\"}");
        }
    }

    // 处理报警（标记为已处理，记录处理人）
    private void handleAlarm(HttpServletRequest request, PrintWriter out) {
        String idParam = request.getParameter("id");
        String handler = request.getParameter("handler");

        if (idParam == null || handler == null || handler.trim().isEmpty()) {
            out.println("{\"error\": \"缺少必要参数(id/handler)\"}");
            return;
        }

        try {
            int id = Integer.parseInt(idParam);
            try (Connection conn = getConnection();
                 PreparedStatement pstmt = conn.prepareStatement(
                         "UPDATE alarm_info SET " +
                                 "status = '已处理', " +
                                 "handler = ?, " +
                                 "handle_time = NOW() " +
                                 "WHERE id = ?")) {

                pstmt.setString(1, handler);
                pstmt.setInt(2, id);

                int rows = pstmt.executeUpdate();
                if (rows > 0) {
                    out.println("{\"success\": true}");
                } else {
                    out.println("{\"error\": \"未找到记录（ID=" + id + "）\"}");
                }
            }
        } catch (NumberFormatException e) {
            out.println("{\"error\": \"参数格式错误 - id必须为数字\"}");
        } catch (SQLException e) {
            e.printStackTrace();
            out.println("{\"error\": \"处理失败 - " + e.getMessage() + "\"}");
        }
    }

    // 删除报警记录（同时删除关联的预案关系）
    private void deleteAlarm(HttpServletRequest request, PrintWriter out) {
        String idParam = request.getParameter("id");
        if (idParam == null || idParam.trim().isEmpty()) {
            out.println("{\"error\": \"缺少必要参数(id)\"}");
            return;
        }

        try {
            int id = Integer.parseInt(idParam);
            try (Connection conn = getConnection()) {
                // 先删除关联的预案关系
                PreparedStatement deleteRelationStmt = conn.prepareStatement(
                        "DELETE FROM alarm_plan_relation WHERE alarm_id = ?"
                );
                deleteRelationStmt.setInt(1, id);
                deleteRelationStmt.executeUpdate();

                // 再删除报警记录
                PreparedStatement deleteAlarmStmt = conn.prepareStatement("DELETE FROM alarm_info WHERE id = ?");
                deleteAlarmStmt.setInt(1, id);
                int rows = deleteAlarmStmt.executeUpdate();

                if (rows > 0) {
                    out.println("{\"success\": true}");
                } else {
                    out.println("{\"error\": \"未找到记录（ID=" + id + "）\"}");
                }
            }
        } catch (NumberFormatException e) {
            out.println("{\"error\": \"参数格式错误 - id必须为数字\"}");
        } catch (SQLException e) {
            e.printStackTrace();
            out.println("{\"error\": \"删除失败 - " + e.getMessage() + "\"}");
        }
    }

    // 获取阈值（用于判断火情等级，匹配对应应急预案）
    private double getThresholdValue(String paramType) throws SQLException {
        try (Connection conn = getConnection();
             PreparedStatement pstmt = conn.prepareStatement("SELECT threshold_value FROM threshold_config WHERE param_type = ?")) {

            pstmt.setString(1, paramType);
            ResultSet rs = pstmt.executeQuery();
            if (rs.next()) {
                return rs.getDouble("threshold_value");
            }
            // 默认阈值（可根据实际业务调整，用于匹配应急预案类型）
            if ("温度".equals(paramType)) return 38.0;  // 超过38℃触发报警
            if ("湿度".equals(paramType)) return 80.0;  // 超过80%触发报警
            if ("烟雾浓度".equals(paramType)) return 50.0;  // 超过50ppm触发报警
            throw new SQLException("未找到参数类型的阈值配置：" + paramType);
        }
    }

    // 日期格式化
    private String formatDateTime(Timestamp timestamp) {
        if (timestamp == null) return "";
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        return sdf.format(timestamp);
    }

    // 数据库连接
    private Connection getConnection() throws SQLException {
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            throw new SQLException("JDBC驱动加载失败", e);
        }
        return DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD);
    }

    // JSON特殊字符转义（新增：避免报警内容中的特殊字符破坏JSON格式）
    private String escapeJson(String value) {
        if (value == null) return "";
        return value.replace("\"", "\\\"")
                .replace("\n", "\\n")
                .replace("\r", "\\r");
    }
}